package com.maimao.user.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.maimao.api.user.UserApi;
import com.maimao.core.constant.Constants;
import com.maimao.core.constant.RedisKeys;
import com.maimao.core.enums.RespCode;
import com.maimao.core.model.auth.AuthUser;
import com.maimao.core.model.resp.PageResult;
import com.maimao.core.model.resp.Result;
import com.maimao.core.utils.RegexUtils;
import com.maimao.model.common.StatusInput;
import com.maimao.model.email.enums.EmailTypeEnum;
import com.maimao.model.user.User;
import com.maimao.model.user.input.EmailInput;
import com.maimao.model.user.input.RegisterInput;
import com.maimao.model.user.input.UpdateIntegralInput;
import com.maimao.model.user.input.UpdatePwdInput;
import com.maimao.model.user.sys.vo.Permissions;
import com.maimao.model.user.vo.VerifyMethod;
import com.maimao.user.controller.base.BaseController;
import com.maimao.user.mapper.UserMapper;
import com.maimao.user.service.UserService;
import io.seata.core.context.RootContext;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Map;

import static com.maimao.core.constant.Constants.ONE;
import static com.maimao.core.constant.Constants.ZERO;

/**
 * @author MaoLin Wang
 * @date 2020/12/13 9:59 下午
 */
@RestController
public class UserController extends BaseController implements UserApi {

    @Autowired
    private UserService userService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private DefaultKaptcha defaultKaptcha;

    /**
     * 根据用户名查询会员权限信息
     */
    @Override
    @GetMapping("/permissions-g/uname")
    public Result<?> getMemberPermissionByUsername(@RequestParam("username") String username) {
        if (StringUtils.isEmpty(username)) {
            return Result.fail(RespCode.NOT_VALID, "用户名为空");
        }
        Permissions permissions = userService.getPermissionsByUsername(username);
        return new Result<>(200, permissions, true, "ok");
    }

    /**
     * 根据手机号查询会员权限信息
     */
    @Override
    @GetMapping("/permissions-g/mobile")
    public Result<?> getMemberPermissionByMobile(@RequestParam("mobile") String mobile) {
        if (StringUtils.isEmpty(mobile) || !RegexUtils.checkMobile(mobile)) {
            return Result.fail(RespCode.NOT_VALID, "手机号非法");
        }
        Permissions permissions = userService.getPermissionsByMobile(mobile);
        return new Result<>(200, permissions, true, "ok");
    }


    /**
     * 根据邮箱查询会员权限
     */
    @Override
    @GetMapping("/permissions-g/email")
    public Result<?> getMemberPermissionByEmail(String email) {
        if (StringUtils.isEmpty(email) || !RegexUtils.checkEmail(email)) {
            return Result.fail(RespCode.NOT_VALID, "邮箱格式非法");
        }
        Permissions permissions = userService.getPermissionsByEmail(email);
        return new Result<>(200, permissions, true, "ok");
    }

    /**
     * 根据用户id查询证件地址
     */
    @Override
    @GetMapping("/idcard-images")
    public Result<?> getIdCardUrlByUid(@RequestParam("userId") Long userId) {
        if (userId == null || userId < 1) {
            return Result.okData(null);
        }

        return Result.okData(userService.getIdCardUrlByUid(userId));
    }

    /**
     * 根据用户id查询证件信息 包括店铺状态
     */
    @Override
    @GetMapping("/idcard-info")
    public Result<?> getIdCardInfoByUid(@RequestParam("userId") Long userId) {
        if (userId == null || userId < 1) {
            return Result.okData(null);
        }

        return Result.okData(userService.getIdCardInfoByUid(userId));
    }

    @Override
    @PostMapping("/idcard-update")
    public Result<?> updateIdCard(@RequestBody Map<String, String> updateParams) {
        if (updateParams == null) {
            logger.warn("修改证件 参数非法");
            return Result.notValid();
        }
        String userId = updateParams.get(Constants.ID);
        if (StringUtils.isEmpty(userId)) {
            logger.warn("修改证件 参数非法");
            return Result.notValid();
        }
        boolean res = userService.updateIdCard(userId, updateParams);

        return res ? Result.ok() : Result.notValid("证件类型非法");
    }

    /**
     * 申请开通店铺
     *
     * @return
     */
    @Override
    @PostMapping("/apply-shop")
    public Result<?> applyShop() {
        AuthUser authUser = checkAndGetAuthUser();
        boolean res = userService.updateShopStatus(Long.valueOf(authUser.getId()));
        if (!res) {
            return Result.notValid("请先上传证件照的正反和手持照片");
        }
        return Result.ok();
    }

    /**
     * 新用户注册
     */
    @Override
    @PostMapping("/member-register")
    public Result<?> register(@Valid @RequestBody RegisterInput registerInput, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return entityInvalid(bindingResult);
        }
        String cacheCode = stringRedisTemplate.opsForValue().get(RedisKeys.LOGIN_MOBILE_PREFIX + registerInput.getMobile());
        if (StringUtils.isEmpty(cacheCode)) {
            return Result.fail("验证码已失效");
        }
        return userService.register(registerInput);

    }

    /**
     * 查询用户积分
     */
    @Override
    @GetMapping("/query-integral")
    public Result<?> queryUserIntegral(@RequestParam("userId") String userId) {
        if (StringUtils.isEmpty(userId)) {
            return Result.notValid();
        }

        return Result.okData(userService.queryIntegral(Long.valueOf(userId)));
    }

    /**
     * 修改用户积分
     */
    @PostMapping("/client/update-integral")
    @Override
    public Result updateIntegral(@RequestBody UpdateIntegralInput integralInput) {
        if (integralInput.getIntegral() == null || integralInput.getUserId() == null ||
                integralInput.getUseIntegral() == null || integralInput.getCancel() == null) {
            return Result.notValid();
        }
        HttpServletRequest request = getRequest();
        String xid = request.getHeader(RootContext.KEY_XID);
        RootContext.bind(xid);
        userService.updateIntegral(integralInput);
        return Result.ok();
    }

    /**
     * 查询用户名（当前是卖家订单查询调用）
     */
    @Override
    @GetMapping("/query-username")
    public Result<?> queryUserNameById(@RequestParam("id") Long id) {
        String username = userService.queryUserName(id);
        return Result.okData(username);
    }

    /**
     * 后台条件查询用户 可查参数：id、username、gender、mobile、status ,状态类参数为-1表示不查询
     *
     * @param params 查询参数
     * @param page   页
     * @param size   每页大小
     * @return 分页用户数据
     */
    @PostMapping("/ms/list")
    @Override
    public Result<?> listUser(@RequestBody User params, @RequestParam(value = "page", defaultValue = "1") Integer page,
                                             @RequestParam(value = "size", defaultValue = "20") Integer size) {

        return new Result<>(RespCode.OK.getCode(), userService.listUser(params, page, size), true, RespCode.OK.getMsg());
    }

    /**
     * 找回密码发送邮件
     */
    @PostMapping("/sendBackPwdEmail")
    @Override
    public Result<?> updatePwdSendEmail(@RequestBody EmailInput input) {
        if (input == null || StrUtil.isEmpty(input.getEmail())) {
            return Result.notValid("邮箱非法");
        }
        AuthUser authUser = checkAndGetAuthUser();
        String targetEmail = userMapper.selectEmailById(authUser.getId2Long());
        if (StrUtil.isEmpty(targetEmail) || !input.getEmail().equals(targetEmail)) {
            return Result.notValid("邮箱不正确");
        }
        HttpServletRequest request = getRequest();
        userService.sendBackEmail(input.getEmail(), EmailTypeEnum.UPDATE_PWD.getType(), request, authUser.getId());
        return Result.ok("邮件发送成功，请注意查收");
    }

    /**
     * 校验修改密码链接uuid
     *
     * @param uuid uuid
     * @return true or false
     */
    @GetMapping("/verifyUUID")
    @Override
    public Result<?> verifyEmailUUID(@RequestParam("uuid") String uuid) {
        if (StrUtil.isEmpty(uuid)) {
            return Result.notValid();
        }
        AuthUser authUser = checkAndGetAuthUser();
        if (isUUIDInvalid(authUser.getId(), uuid)) {
            return Result.notValid("链接已过期，请重新操作");
        }
        return Result.okData(true);
    }


    private boolean isUUIDInvalid(String userId, String uuid) {
        String target = (String) redisTemplate.opsForValue().get(String.format(RedisKeys.UPDATE_PWD_UID, userId));
        if (StrUtil.isEmpty(target) || !target.equals(uuid)) {
            return true;
        }
        return false;
    }

    /**
     * 修改密码
     *
     * @param input input
     */
    @PostMapping("/updatePwd")
    @Override
    public Result<?> updatePwd(@RequestBody @Validated UpdatePwdInput input) {
        AuthUser authUser = checkAndGetAuthUser();
        Object validated = redisTemplate.opsForValue().get(RedisKeys.VALIDATED + authUser.getId());
        if (null == validated || !Convert.toInt(validated).equals(ONE)) {
            return Result.notValid("认证失效，请重新获取验证码");
        }
        return userService.updatePwd(input.getRawPwd(), input.getNewPwd(), authUser.getId2Long());
    }

    @Override
    public Result<?> bindEmailSendEmailCode(EmailInput input) {
        String text = defaultKaptcha.createText();
        return null;
    }

    /**
     * 查询用户可用的认证方式
     */
    @GetMapping("/queryVerifyMethod")
    @Override
    public Result<?> queryVerifyMethod() {
        AuthUser authUser = checkAndGetAuthUser();
        return userService.queryVerifyMethod(authUser.getId2Long());
    }

    /**
     * 绑定邮箱
     */
    @Override
    @PostMapping("/bindEmail")
    public Result<?> bindEmail(@RequestBody @Validated EmailInput input) {
        if (StrUtil.isEmpty(input.getCode())) {
            return Result.notValid("请输入验证码");
        }
        Object code = redisTemplate.opsForValue().get(RedisKeys.SECURITY_OPERATION_EMAIL_CODE + input.getEmail());

        if (null == code) {
            return Result.notValid("验证码已失效，请重新获取");
        }
        if (!code.equals(input.getCode())) {
            return Result.notValid("验证码错误");
        }
        User user = userMapper.selectByEmail(input.getEmail());
        if (null != user) {
            return Result.notValid("邮箱已注册");
        }
        AuthUser authUser = checkAndGetAuthUser();
        userService.bindEmail(input.getEmail(), authUser.getId2Long());
        return Result.ok("绑定成功！");
    }

    /**
     * 冻结/恢复用户
     */
    @PostMapping("/freezeRestore")
    @Override
    public Result<?> freezeRestore(@RequestBody @Validated StatusInput input) {
        if (input.getStatus().equals(ONE) || input.getStatus().equals(ZERO)) {
            userService.freezeRestore(input.getId(), input.getStatus());
            return Result.ok(input.getStatus().equals(ONE) ? "恢复成功" : "冻结成功");
        }
        return Result.notValid();
    }

    /**
     * 用户个人基本信息
     */
    @Override
    @GetMapping("/baseInfo")
    public Result<?> baseInfo() {
        AuthUser authUser = checkAndGetAuthUser();
        return Result.okData(userService.baseInfo(authUser.getId2Long()));
    }

    /**
     * 修改基本信息
     */
    @Override
    @PostMapping("/updateBaseInfo")
    public Result<?> updateBaseInfo(@RequestBody User user) {
        AuthUser authUser = checkAndGetAuthUser();
        userService.updateBaseInfo(authUser.getId2Long(), user.getGender(), user.getBirthday());
        return Result.ok("更新成功");
    }


}
